--[[Redis缓存driver]]
local _rds = class('RedisInc')
-- ====================================================
--default params
local redis_c = require('resty.redis')
local d = Ding
local Logger = d.Logger

--连接池的实际作用(管理类的连接池实现暂时不需要)
local IDLE_TIMEOUT = 10 * 1000 --10s
local KEEPALIVE_CNE = 10 --连接池的数量
local json = require('cjson')
-- ====================================================
_rds.dtype = 'redis'

---构造函数
--@tparam string host
--@tparma string port
function _rds:ctor(host, port)
    self._inc = redis_c:new()
    self._iscon = false
    self._is_lazyinit = false
end

---连接
--@tparam string host host
--@tparam string port port
--@tparam string auth auth
function _rds:connect(cfg)
    local host, port, auth = cfg['host'], cfg['port'], cfg['auth']
    self._inc:set_timeout(self.TIMEOUT)
    local ok, err = self._inc:connect(host, port)
    if not ok then
        Logger:error('failed to connect: %s:%s', host, port)
        return false
    end
    if auth then
        local res, err = self._inc:auth(auth)
        if not res then
            Logger:error('failed to auth:%s, pwd is %s', host, port, auth)
            return false
        else
            if not self._is_lazyinit then
                self:_lazy_init(cfg)
            end
        end
    end
    self._iscon = true
    return true
end

---断开连接
--@param isimmedia 是否立即断开
function _rds:close(isimmedia)
    if isimmedia then
        self._inc:close()
        return
    end
    Logger:debug('close the redis connect!')
    self._inc:set_keepalive(IDLE_TIMEOUT, KEEPALIVE_CNE)
end

--- 从列表中截取min-max个数据
-- redis的lrange获取
-- @tparam  table self
-- @tparam  string kname redis-key
-- @tparam  number min 最小
-- @tparam  number max 最大
function _rds:fetch_limitcnt(kname, min, max)
    return self:lrange(kname, tonumber(min), tonumber(max))
end

function _rds:insert_data(kname, val)
    if self._iscon and self._inc then
        if type(val) ~= 'table' then
            return self:mset(kname, val)
        else
            return self._inc:hmset(kname, val)
        end
    end
end

function _rds:lpush_data(kname, obj)
    if self._iscon and self._inc then
        return self:lpush(kname, json.encode(obj))
    end
end

function _rds:find_one(kname, lcond)
    local ishash = (type(lcond) == 'table' and #lcond > 0)
    if ishash then
        return self._inc:hmget(kname, unpack(lcond))
    else
        return self._inc:get(kname)
    end
end

function _rds:find_all(kname, lcond)
    return self:find_one(kname, lcond)
end

function _rds:update(kname, model)
    local n_val = self:find_one(kname)
    return self._inc:insert_data(kname, model)
end

function _rds:dele_one(kname)
    return self._inc:del(kname)
end

--默认直接把inc方法赋给这个类
function _rds:_lazy_init(cfg)
    local common_cmds = {
        'get',
        'set',
        'mget',
        'mset',
        'del',
        'incr',
        'incrby',
        'decr', -- Strings
        'llen',
        'lindex',
        'lpop',
        'lpush',
        'lrange',
        'linsert', -- Lists
        'hexists',
        'hget',
        'hset',
        'hmget',
        --[[ "hmset", ]] 'hdel', -- Hashes
        'smembers',
        'sismember',
        'sadd',
        'srem',
        'sdiff',
        'sinter',
        'sunion', -- Sets
        'zrange',
        'zrangebyscore',
        'zrank',
        'zadd',
        'zrem',
        'zincrby', -- Sorted Sets
        'auth',
        'eval',
        'expire',
        'script',
        'sort' -- Others
    }
    local sub_commands = {
        'subscribe',
        'psubscribe',
        'publish'
    }

    -- local m = {}
    table.merge(common_cmds, sub_commands)
    for _, cmd in ipairs(common_cmds) do
        self[cmd] = function(self, ...)
            Logger:debug('redis on [%s:%s] cmd [%s] execute ', cfg['host'], cfg['port'], cmd)
            return self._inc[cmd](self._inc, ...)
        end
    end
    self._is_lazyinit = true
end

return _rds
